package com.skyz.base.manager;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.OkHttpClient;
import okhttp3.internal.platform.Platform;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static android.util.Log.INFO;
import static android.util.Log.e;

public class RetrofitManager {

    private final String TAG = getClass().getSimpleName();

    private RetrofitManager() {
    }

    private static class InstanceHolder {
        private static final RetrofitManager instance = new RetrofitManager();
    }

    public static RetrofitManager getInstance() {
        return InstanceHolder.instance;
    }

    private final List<RetrofitService> mRetrofitServiceList = new ArrayList<>();

    public void init(List<EnvironmentManager.Environment> environmentList, OkHttpClient okHttpClient) {
        if (environmentList != null) {
            for (EnvironmentManager.Environment environment : environmentList) {
                Retrofit retrofit = initRetrofit(environment, okHttpClient);
                mRetrofitServiceList.add(new RetrofitService(retrofit));
            }
        }
    }

    private Retrofit initRetrofit(EnvironmentManager.Environment environment, OkHttpClient okHttpClient) {

        HttpLoggingInterceptor.Logger logger = new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(@NonNull String message) {
                Platform.get().log(message, INFO, null);
                if (SystemManager.getInstance().getNetLogToFile()) {
                    FileLoggerManager.getInstance().logNet(message);
                }
            }
        };
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(logger);
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        if (okHttpClient == null) {
            okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build();
        } else {
            okHttpClient = okHttpClient.newBuilder().addInterceptor(httpLoggingInterceptor).build();
        }
        return new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(environment.getBaseUrl())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build();

    }

    public <T> T getService(final Class<T> service) {
        if (service == null) {
            throw new RuntimeException("service can not be null");
        }
        RetrofitService retrofitService = getRetrofitService();
        if (retrofitService == null) {
            throw new RuntimeException("init retrofit manager first");
        }

        Retrofit retrofit = retrofitService.getRetrofit();
        Map<String, Object> serviceMap = retrofitService.getServiceMap();

        String name = service.getName();
        Object obj = serviceMap.get(name);
        if (obj != null) {
            return (T) obj;
        } else {
            T t = retrofit.create(service);
            serviceMap.put(name, t);
            return t;
        }
    }

    private RetrofitService getRetrofitService() {
        int checkedEnvironmentIndex = EnvironmentManager.getInstance().getCheckedEnvironmentIndex();
        return mRetrofitServiceList.get(checkedEnvironmentIndex);
    }


    private static class RetrofitService {
        private final Retrofit mRetrofit;
        private final Map<String, Object> mServiceMap = new HashMap<>();

        public RetrofitService(Retrofit mRetrofit) {
            this.mRetrofit = mRetrofit;
        }

        public Retrofit getRetrofit() {
            return mRetrofit;
        }

        public Map<String, Object> getServiceMap() {
            return mServiceMap;
        }
    }
}
